package disease

import (
	"bytes"
	"fmt"
	"gitee.com/g-qs/gin-vue-admin/server/global"
	adminReq "gitee.com/g-qs/gin-vue-admin/server/model/admin/request"
	adminRes "gitee.com/g-qs/gin-vue-admin/server/model/admin/response"
	"gitee.com/g-qs/gin-vue-admin/server/model/assess"
	"gitee.com/g-qs/gin-vue-admin/server/model/catering"
	"gitee.com/g-qs/gin-vue-admin/server/model/disease"
	diseaseReq "gitee.com/g-qs/gin-vue-admin/server/model/disease/request"
	diseaseRes "gitee.com/g-qs/gin-vue-admin/server/model/disease/response"
	"gitee.com/g-qs/gin-vue-admin/server/model/health"
	"gitee.com/g-qs/gin-vue-admin/server/model/health/request"
	healthRes "gitee.com/g-qs/gin-vue-admin/server/model/health/response"
	"gitee.com/g-qs/gin-vue-admin/server/model/hierarchy"
	"gitee.com/g-qs/gin-vue-admin/server/model/system"
	"gitee.com/g-qs/gin-vue-admin/server/model/user"
	"gitee.com/g-qs/gin-vue-admin/server/utils"
	"github.com/pkg/errors"
	"github.com/xuri/excelize/v2"
	"gorm.io/gorm"
	"math"
	"sort"
	"strconv"
	"strings"
	"time"
)

type DiseaseService struct {
}

type Term struct {
	ID   int
	Name string
}

// GetDiseaseTypeList 获取病症类型列表
func (ds *DiseaseService) GetDiseaseTypeList() (list []disease.DiseaseType, err error) {
	err = global.GVA_DB.Model(&disease.DiseaseType{}).Find(&list).Error
	return
}

// GetDiseaseList 根据病症类型ID获取病症列表
func (ds *DiseaseService) GetDiseaseList(db []string) (disease []health.Disease, err error) {
	global.GVA_DB.Where("bzlx_id IN (?)", db).Find(&disease)
	return
}

// GetDiseaseRank 根据条件获取病症排行
func (ds *DiseaseService) GetDiseaseRank(info diseaseReq.DiseaseRank) (list []diseaseRes.DiseaseRank, total int64, err error) {
	db := global.GVA_DB.Model(&disease.DiseaseReportRecord{}).Select("uid, bz_ids")
	var users []user.User
	var serviceCentres system.SysUser
	var serviceStations []system.SysUser
	var records []disease.DiseaseReportRecord
	var diseaseList []disease.Disease
	// 如果有条件搜索 下方会自动创建搜索语句
	var userIDs []uint
	if info.ServiceCenterID != 0 && info.ServiceStationID != 0 && info.HmID != 0 { // 如果存在所属健管师查询条件
		usersErr := global.GVA_DB.Where("steward_id = ?", info.HmID).Find(&users).Error
		if usersErr != nil {
			return nil, 0, usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.ServiceCenterID != 0 { // 如果存在所属服务中心查询条件
		ServiceCentreErr := global.GVA_DB.Where("authority_id = 333 AND id = ?", info.ServiceCenterID).First(&serviceCentres).Error
		if ServiceCentreErr != nil {
			return nil, 0, ServiceCentreErr
		}
		ServiceStationsErr := global.GVA_DB.Where("authority_id = 444 AND creator = ?", serviceCentres.ID).Find(&serviceStations).Error
		if ServiceStationsErr != nil {
			return nil, 0, ServiceStationsErr
		}
		var ServiceCenterIDs []uint
		for _, v := range serviceStations {
			ServiceCenterIDs = append(ServiceCenterIDs, v.ID)
		}
		usersErr := global.GVA_DB.Where("service_center_id IN (?)", ServiceCenterIDs).Find(&users).Error
		if usersErr != nil {
			return nil, 0, usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.ServiceStationID != 0 && info.ServiceCenterID != 0 { // 如果存在所属服务站查询条件
		usersErr := global.GVA_DB.Where("service_center_id IN (?)", info.ServiceStationID).Find(&users).Error
		if usersErr != nil {
			return nil, 0, usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	//if info.Province != 0 {
	//	usersErr := global.GVA_DB.Where("province = ?", info.Province).Find(&users).Error
	//	if usersErr != nil {
	//		return nil, 0, usersErr
	//	}
	//	//var userIDs []uint
	//	for _, v := range users {
	//		userIDs = append(userIDs, v.ID)
	//	}
	//	db = db.Where("uid IN (?)", userIDs)
	//}
	//if info.City != 0 {
	//	usersErr := global.GVA_DB.Where("city = ?", info.City).Find(&users).Error
	//	if usersErr != nil {
	//		return nil, 0, usersErr
	//	}
	//	//var userIDs []uint
	//	for _, v := range users {
	//		userIDs = append(userIDs, v.ID)
	//	}
	//	db = db.Where("uid IN (?)", userIDs)
	//}
	if info.Province != 0 && info.City != 0 && info.Area != 0 {
		usersErr := global.GVA_DB.Where("area = ?", info.Area).Find(&users).Error
		if usersErr != nil {
			return nil, 0, usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	// 1.获取每个用户最新病症记录
	err = db.Order("created_at DESC").Group("uid").Find(&records).Error
	if err != nil {
		return
	}
	// 2.获取全部病症
	bzdb := global.GVA_DB.Model(&disease.Disease{})
	if info.ID != 0 { // 如果存在病症ID
		bzdb = bzdb.Where("id = (?)", info.ID)
	}
	diseaseErr := bzdb.Count(&total).Error
	if diseaseErr != nil {
		return nil, 0, diseaseErr
	}
	bzdb.Find(&diseaseList)
	diseaseMap := make(map[uint]diseaseRes.DiseaseRank)
	for _, bz := range diseaseList { // 赋值返回结构体
		diseaseMap[bz.ID] = diseaseRes.DiseaseRank{
			ID:         bz.ID,
			Name:       bz.Name,
			Number:     0,
			UIDs:       "",
			Proportion: 0,
		}
	}
	// 3. 统计每个病症出现的次数和用户ID集合
	userIDsMap := make(map[uint]struct{})
	for _, record := range records {
		bzIDs := strings.Split(record.BzIDs, ",")
		for _, bzIDStr := range bzIDs {
			bzID := uint(0)
			fmt.Sscanf(bzIDStr, "%d", &bzID)
			if rank, exists := diseaseMap[bzID]; exists {
				rank.Number++
				if rank.UIDs == "" {
					rank.UIDs = fmt.Sprintf("%d", record.Uid)
				} else {
					rank.UIDs += fmt.Sprintf(",%d", record.Uid)
				}
				diseaseMap[bzID] = rank
			}
			userIDsMap[record.Uid] = struct{}{}
		}
	}
	// 4. 计算比例
	totalOccurrences := uint(0)
	for _, rank := range diseaseMap {
		totalOccurrences += rank.Number
	}
	for id, rank := range diseaseMap {
		if totalOccurrences > 0 {
			rank.Proportion = math.Round((float64(rank.Number)/float64(totalOccurrences)*100)*100) / 100
		}
		diseaseMap[id] = rank
	}
	// 5. 按次数倒序排序
	for _, value := range diseaseMap {
		list = append(list, value)
	}
	sort.Slice(list, func(i, j int) bool {
		return list[i].Number > list[j].Number
	})
	return
}

// GetScDiseaseRank 获取病症排行【服务中心】
func (ds *DiseaseService) GetScDiseaseRank(info diseaseReq.DiseaseRank) (list []diseaseRes.DiseaseRank, total int64, err error) {
	db := global.GVA_DB.Model(&disease.DiseaseReportRecord{}).Select("uid, bz_ids")
	var users []user.User
	var serviceCentres system.SysUser
	var serviceStations []system.SysUser
	var records []disease.DiseaseReportRecord
	var diseaseList []disease.Disease
	// 如果有条件搜索 下方会自动创建搜索语句
	var userIDs []uint
	if info.ServiceStationID != 0 && info.HmID != 0 { // 如果存在所属健管师查询条件
		usersErr := global.GVA_DB.Where("steward_id = ?", info.HmID).Find(&users).Error
		if usersErr != nil {
			return nil, 0, usersErr
		}
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.ServiceStationID != 0 { // 如果存在所属服务站查询条件
		usersErr := global.GVA_DB.Where("service_center_id IN (?)", info.ServiceStationID).Find(&users).Error
		if usersErr != nil {
			return nil, 0, usersErr
		}
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	} else {
		ServiceCentreErr := global.GVA_DB.Where("authority_id = 333 AND id = ?", info.ServiceCenterID).First(&serviceCentres).Error
		if ServiceCentreErr != nil {
			return nil, 0, ServiceCentreErr
		}
		ServiceStationsErr := global.GVA_DB.Where("authority_id = 444 AND creator = ?", serviceCentres.ID).Find(&serviceStations).Error
		if ServiceStationsErr != nil {
			return nil, 0, ServiceStationsErr
		}
		var ServiceCenterIDs []uint
		for _, v := range serviceStations {
			ServiceCenterIDs = append(ServiceCenterIDs, v.ID)
		}
		usersErr := global.GVA_DB.Where("service_center_id IN (?)", ServiceCenterIDs).Find(&users).Error
		if usersErr != nil {
			return nil, 0, usersErr
		}
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.Province != 0 && info.City != 0 && info.Area != 0 {
		usersErr := global.GVA_DB.Where("area = ?", info.Area).Find(&users).Error
		if usersErr != nil {
			return nil, 0, usersErr
		}
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	// 1.获取每个用户最新病症记录
	err = db.Order("created_at DESC").Group("uid").Find(&records).Error
	if err != nil {
		return
	}
	// 2.获取全部病症
	bzdb := global.GVA_DB.Model(&disease.Disease{})
	if info.ID != 0 { // 如果存在病症ID
		bzdb = bzdb.Where("id = (?)", info.ID)
	}
	diseaseErr := bzdb.Count(&total).Error
	if diseaseErr != nil {
		return nil, 0, diseaseErr
	}
	bzdb.Find(&diseaseList)
	diseaseMap := make(map[uint]diseaseRes.DiseaseRank)
	for _, bz := range diseaseList { // 赋值返回结构体
		diseaseMap[bz.ID] = diseaseRes.DiseaseRank{
			ID:         bz.ID,
			Name:       bz.Name,
			Number:     0,
			UIDs:       "",
			Proportion: 0,
		}
	}
	// 3. 统计每个病症出现的次数和用户ID集合
	userIDsMap := make(map[uint]struct{})
	for _, record := range records {
		bzIDs := strings.Split(record.BzIDs, ",")
		for _, bzIDStr := range bzIDs {
			bzID := uint(0)
			fmt.Sscanf(bzIDStr, "%d", &bzID)
			if rank, exists := diseaseMap[bzID]; exists {
				rank.Number++
				if rank.UIDs == "" {
					rank.UIDs = fmt.Sprintf("%d", record.Uid)
				} else {
					rank.UIDs += fmt.Sprintf(",%d", record.Uid)
				}
				diseaseMap[bzID] = rank
			}
			userIDsMap[record.Uid] = struct{}{}
		}
	}
	// 4. 计算比例
	totalOccurrences := uint(0)
	for _, rank := range diseaseMap {
		totalOccurrences += rank.Number
	}
	for id, rank := range diseaseMap {
		if totalOccurrences > 0 {
			rank.Proportion = math.Round((float64(rank.Number)/float64(totalOccurrences)*100)*100) / 100
		}
		diseaseMap[id] = rank
	}
	// 5. 按次数倒序排序
	for _, value := range diseaseMap {
		list = append(list, value)
	}
	sort.Slice(list, func(i, j int) bool {
		return list[i].Number > list[j].Number
	})
	return
}

// ExportDiseaseRankExcel 根据条件导出病症排行Excel
func (ds *DiseaseService) ExportDiseaseRankExcel(info diseaseReq.DiseaseRank) (file *bytes.Buffer, name string, err error) {
	db := global.GVA_DB.Model(&disease.DiseaseReportRecord{}).Select("uid, bz_ids")
	var users []user.User
	var serviceCentres system.SysUser
	var serviceStations []system.SysUser
	var records []disease.DiseaseReportRecord
	var diseaseList []disease.Disease
	var list []diseaseRes.DiseaseRank
	// 如果有条件搜索 下方会自动创建搜索语句
	var userIDs []uint
	if info.ServiceCenterID != 0 && info.ServiceStationID != 0 && info.HmID != 0 { // 如果存在所属健管师查询条件
		usersErr := global.GVA_DB.Where("steward_id = ?", info.HmID).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.ServiceCenterID != 0 { // 如果存在所属服务中心查询条件
		ServiceCentreErr := global.GVA_DB.Where("authority_id = 333 AND id = ?", info.ServiceCenterID).First(&serviceCentres).Error
		if ServiceCentreErr != nil {
			return nil, "", ServiceCentreErr
		}
		ServiceStationsErr := global.GVA_DB.Where("authority_id = 444 AND creator = ?", serviceCentres.ID).Find(&serviceStations).Error
		if ServiceStationsErr != nil {
			return nil, "", ServiceStationsErr
		}
		var ServiceCenterIDs []uint
		for _, v := range serviceStations {
			ServiceCenterIDs = append(ServiceCenterIDs, v.ID)
		}
		usersErr := global.GVA_DB.Where("service_center_id IN (?)", ServiceCenterIDs).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.ServiceStationID != 0 && info.ServiceCenterID != 0 { // 如果存在所属服务站查询条件
		usersErr := global.GVA_DB.Where("service_center_id IN (?)", info.ServiceStationID).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.Province != 0 {
		usersErr := global.GVA_DB.Where("province = ?", info.Province).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.City != 0 {
		usersErr := global.GVA_DB.Where("city = ?", info.City).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.Area != 0 {
		usersErr := global.GVA_DB.Where("area = ?", info.Area).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	// 1.获取每个用户最新病症记录
	err = db.Order("created_at DESC").Group("uid").Find(&records).Error
	if err != nil {
		return
	}
	// 2.获取全部病症
	global.GVA_DB.Model(&disease.Disease{}).Find(&diseaseList)
	diseaseMap := make(map[uint]diseaseRes.DiseaseRank)
	for _, bz := range diseaseList { // 赋值返回结构体
		diseaseMap[bz.ID] = diseaseRes.DiseaseRank{
			ID:         bz.ID,
			Name:       bz.Name,
			Number:     0,
			UIDs:       "",
			Proportion: 0,
		}
	}
	// 3. 统计每个病症出现的次数和用户ID集合
	userIDsMap := make(map[uint]struct{})
	for _, record := range records {
		bzIDs := strings.Split(record.BzIDs, ",")
		for _, bzIDStr := range bzIDs {
			bzID := uint(0)
			fmt.Sscanf(bzIDStr, "%d", &bzID)
			if rank, exists := diseaseMap[bzID]; exists {
				rank.Number++
				if rank.UIDs == "" {
					rank.UIDs = fmt.Sprintf("%d", record.Uid)
				} else {
					rank.UIDs += fmt.Sprintf(",%d", record.Uid)
				}
				diseaseMap[bzID] = rank
			}
			userIDsMap[record.Uid] = struct{}{}
		}
	}
	// 4. 计算比例
	totalOccurrences := uint(0)
	for _, rank := range diseaseMap {
		totalOccurrences += rank.Number
	}
	for id, rank := range diseaseMap {
		if totalOccurrences > 0 {
			rank.Proportion = math.Round((float64(rank.Number)/float64(totalOccurrences)*100)*100) / 100
		}
		diseaseMap[id] = rank
	}
	// 5. 按次数倒序排序
	for _, value := range diseaseMap {
		list = append(list, value)
	}
	sort.Slice(list, func(i, j int) bool {
		return list[i].Number > list[j].Number
	})
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	// Create a new sheet.
	index, err := f.NewSheet("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}
	tableTitle := []string{"病症", "人数", "比例"}
	var rows [][]string
	rows = append(rows, tableTitle)
	for _, value := range list {
		row := []string{
			value.Name,
			strconv.Itoa(int(value.Number)),
			fmt.Sprintf("%.2f%%", value.Proportion),
		}
		rows = append(rows, row)
	}
	for i, row := range rows {
		for j, colCell := range row {
			err := f.SetCellValue("Sheet1", fmt.Sprintf("%s%d", string('A'+j), i+1), colCell)
			if err != nil {
				return nil, "", err
			}
		}
	}
	f.SetActiveSheet(index)
	file, err = f.WriteToBuffer()
	if err != nil {
		return nil, "", err
	}
	return file, "病症排行表格", err
}

// ExportScDiseaseRankExcel 导出病症排行Excel【服务中心】
func (ds *DiseaseService) ExportScDiseaseRankExcel(info diseaseReq.DiseaseRank) (file *bytes.Buffer, name string, err error) {
	db := global.GVA_DB.Model(&disease.DiseaseReportRecord{}).Select("uid, bz_ids")
	var users []user.User
	var serviceCentres system.SysUser
	var serviceStations []system.SysUser
	var records []disease.DiseaseReportRecord
	var diseaseList []disease.Disease
	var list []diseaseRes.DiseaseRank
	// 如果有条件搜索 下方会自动创建搜索语句
	var userIDs []uint
	ServiceCentreErr := global.GVA_DB.Where("authority_id = 333 AND id = ?", info.ServiceCenterID).First(&serviceCentres).Error
	if ServiceCentreErr != nil {
		return nil, "", ServiceCentreErr
	}
	if info.ServiceStationID != 0 && info.HmID != 0 { // 如果存在所属健管师查询条件
		usersErr := global.GVA_DB.Where("steward_id = ?", info.HmID).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.ServiceStationID != 0 { // 如果存在所属服务站查询条件
		usersErr := global.GVA_DB.Where("service_center_id IN (?)", info.ServiceStationID).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	} else {
		ServiceStationsErr := global.GVA_DB.Where("authority_id = 444 AND creator = ?", serviceCentres.ID).Find(&serviceStations).Error
		if ServiceStationsErr != nil {
			return nil, "", ServiceStationsErr
		}
		var ServiceCenterIDs []uint
		for _, v := range serviceStations {
			ServiceCenterIDs = append(ServiceCenterIDs, v.ID)
		}
		usersErr := global.GVA_DB.Where("service_center_id IN (?)", ServiceCenterIDs).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.Province != 0 {
		usersErr := global.GVA_DB.Where("province = ?", info.Province).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.City != 0 {
		usersErr := global.GVA_DB.Where("city = ?", info.City).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	if info.Area != 0 {
		usersErr := global.GVA_DB.Where("area = ?", info.Area).Find(&users).Error
		if usersErr != nil {
			return nil, "", usersErr
		}
		//var userIDs []uint
		for _, v := range users {
			userIDs = append(userIDs, v.ID)
		}
		db = db.Where("uid IN (?)", userIDs)
	}
	// 1.获取每个用户最新病症记录
	err = db.Order("created_at DESC").Group("uid").Find(&records).Error
	if err != nil {
		return
	}
	// 2.获取全部病症
	global.GVA_DB.Model(&disease.Disease{}).Find(&diseaseList)
	diseaseMap := make(map[uint]diseaseRes.DiseaseRank)
	for _, bz := range diseaseList { // 赋值返回结构体
		diseaseMap[bz.ID] = diseaseRes.DiseaseRank{
			ID:         bz.ID,
			Name:       bz.Name,
			Number:     0,
			UIDs:       "",
			Proportion: 0,
		}
	}
	// 3. 统计每个病症出现的次数和用户ID集合
	userIDsMap := make(map[uint]struct{})
	for _, record := range records {
		bzIDs := strings.Split(record.BzIDs, ",")
		for _, bzIDStr := range bzIDs {
			bzID := uint(0)
			fmt.Sscanf(bzIDStr, "%d", &bzID)
			if rank, exists := diseaseMap[bzID]; exists {
				rank.Number++
				if rank.UIDs == "" {
					rank.UIDs = fmt.Sprintf("%d", record.Uid)
				} else {
					rank.UIDs += fmt.Sprintf(",%d", record.Uid)
				}
				diseaseMap[bzID] = rank
			}
			userIDsMap[record.Uid] = struct{}{}
		}
	}
	// 4. 计算比例
	totalOccurrences := uint(0)
	for _, rank := range diseaseMap {
		totalOccurrences += rank.Number
	}
	for id, rank := range diseaseMap {
		if totalOccurrences > 0 {
			rank.Proportion = math.Round((float64(rank.Number)/float64(totalOccurrences)*100)*100) / 100
		}
		diseaseMap[id] = rank
	}
	// 5. 按次数倒序排序
	for _, value := range diseaseMap {
		list = append(list, value)
	}
	sort.Slice(list, func(i, j int) bool {
		return list[i].Number > list[j].Number
	})
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	// Create a new sheet.
	index, err := f.NewSheet("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}
	tableTitle := []string{"病症", "人数", "比例"}
	var rows [][]string
	rows = append(rows, tableTitle)
	for _, value := range list {
		row := []string{
			value.Name,
			strconv.Itoa(int(value.Number)),
			fmt.Sprintf("%.2f%%", value.Proportion),
		}
		rows = append(rows, row)
	}
	for i, row := range rows {
		for j, colCell := range row {
			err := f.SetCellValue("Sheet1", fmt.Sprintf("%s%d", string('A'+j), i+1), colCell)
			if err != nil {
				return nil, "", err
			}
		}
	}
	f.SetActiveSheet(index)
	file, err = f.WriteToBuffer()
	if err != nil {
		return nil, "", err
	}
	return file, serviceCentres.Name + "病症排行表格", err
}

// GetDiseaseUserList 获取病症用户列表
func (ds *DiseaseService) GetDiseaseUserList(info diseaseReq.DiseaseUser) (list []diseaseRes.DiseaseUser, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&user.User{})
	if info.UIDs != "" {
		IDsStr := strings.Trim(info.UIDs, "[]")
		IDsArr := strings.Split(IDsStr, ",")
		db = db.Where("fd_user.id IN (?)", IDsArr)
	} else {
		db = db.Where("fd_user.id = 0")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	err = db.Select("fd_user.id AS id, fd_user.name AS name, fd_user.sex AS sex, " +
		"IFNULL( TIMESTAMPDIFF( YEAR, fd_user.birthday, CURDATE()), 0 ) AS age,fd_user.phone AS phone," +
		"b.name AS healthManager,b.phone AS servicePhone,c.name AS serviceStation,d.name AS serviceCenter," +
		"(SELECT name FROM geo_provinces WHERE code = fd_user.province) AS province, " +
		"(SELECT name FROM geo_cities WHERE code = fd_user.city) AS city, " +
		"(SELECT name FROM geo_areas WHERE code = fd_user.area) AS area").
		Joins("LEFT JOIN fd_health_manager AS b ON fd_user.steward_id = b.hm_id").
		Joins("LEFT JOIN sys_users AS c ON fd_user.service_center_id = c.id").
		Joins("LEFT JOIN sys_users AS d ON c.creator = d.id").
		Order("fd_user.id ASC").
		Scan(&list).Error
	return
}

// GetSolarTerms 获取当前节气
func (ds *DiseaseService) GetSolarTerms() (data health.SolarTerms, err error) {
	// 获取当前时间
	now := time.Now()
	// 获取年、月、日
	year := now.Year() % 100
	month := int(now.Month())
	day := now.Day()
	coefficient := [][]float64{
		{5.4055, 2019, -1}, //小寒
		{20.12, 2082, 1},   //大寒
		{3.87},             //立春
		{18.74, 2026, -1},  //雨水
		{5.63},             //惊蛰
		{20.646, 2084, 1},  //春分
		{4.81},             //清明
		{20.1},             //谷雨
		{5.52, 1911, 1},    //立夏
		{21.04, 2008, 1},   //小满
		{5.678, 1902, 1},   //芒种
		{21.37, 1928, 1},   //夏至
		{7.108, 2016, 1},   //小暑
		{22.83, 1922, 1},   //大暑
		{7.5, 2002, 1},     //立秋
		{23.13},            //处暑
		{7.646, 1927, 1},   //白露
		{23.042, 1942, 1},  //秋分
		{8.318},            //寒露
		{23.438, 2089, 1},  //霜降
		{7.438, 2089, 1},   //立冬
		{22.36, 1978, 1},   //小雪
		{7.18, 1954, 1},    //大雪
		{21.94, 2021, -1},  //冬至
	}
	termName := []Term{
		{23, "小寒"}, {24, "大寒"}, {1, "立春"}, {2, "雨水"}, {3, "惊蛰"}, {4, "春分"}, {5, "清明"}, {6, "谷雨"},
		{7, "立夏"}, {8, "小满"}, {9, "芒种"}, {10, "夏至"}, {11, "小暑"}, {12, "大暑"}, {13, "立秋"}, {14, "处暑"},
		{15, "白露"}, {16, "秋分"}, {17, "寒露"}, {18, "霜降"}, {19, "立冬"}, {20, "小雪"}, {21, "大雪"}, {22, "冬至"},
	}
	idx1 := (month - 1) * 2
	leapValue := math.Floor(float64(year-1) / 4)
	day1 := math.Floor(float64(year)*0.2422 + coefficient[idx1][0] - leapValue)
	if len(coefficient[idx1]) > 1 && coefficient[idx1][1] == float64(year) {
		day1 += coefficient[idx1][2]
	}
	day2 := math.Floor(float64(year)*0.2422 + coefficient[idx1+1][0] - leapValue)
	if len(coefficient[idx1+1]) > 1 && coefficient[idx1+1][1] == float64(year) {
		day2 += coefficient[idx1+1][2]
	}
	if float64(day) < day1 {
		data.ID = termName[idx1-1].ID
		data.JqName = termName[idx1-1].Name
	} else if float64(day) == day1 {
		data.ID = termName[idx1].ID
		data.JqName = termName[idx1].Name
	} else if float64(day) > day1 && float64(day) < day2 {
		data.ID = termName[idx1].ID
		data.JqName = termName[idx1].Name
	} else if float64(day) == day2 {
		data.ID = termName[idx1+1].ID
		data.JqName = termName[idx1+1].Name
	} else if float64(day) > day2 {
		data.ID = termName[idx1+1].ID
		data.JqName = termName[idx1+1].Name
	}
	return
}

func generateOrderCode(prefix string) string {
	orderCode := prefix + getTime13()
	return orderCode
}

func getTime13() string {
	msec := time.Now().UnixNano() / int64(time.Millisecond)
	return fmt.Sprintf("%d", msec)[:13]
}

// SaveReports 保存报告
func (ds *DiseaseService) SaveReports(record disease.DiseaseReportRecord) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		// 生成唯一报告编号
		reportNumber := generateOrderCode("FD")
		var userEfficacyTag assess.UserEfficacyTag
		// 脑波方案
		var nbDiseaseArticle []request.DiseaseArticle // 未过滤ID
		bzIDs := strings.Split(record.BzIDs, ",")
		// -------------------------------------------------------------获取病症关联脑波部分------------------------------------------------------------- //
		if err := tx.Find(&nbDiseaseArticle, "disease_id in (?) and type = ?", bzIDs, "audio").Error; err != nil {
			return err
		}
		nbids := make([]uint, len(nbDiseaseArticle))
		for i, v := range nbDiseaseArticle {
			nbids[i] = v.ArticleID
		}
		var nbArticle []hierarchy.FdArticleAudio
		//根据一级过滤
		if err = tx.Find(&nbArticle, "id in (?) and level_one_id = ?", nbids, 1).Error; err != nil {
			return err
		}
		nbaids := make([]uint, len(nbArticle))
		for i, v := range nbArticle {
			nbaids[i] = v.ID
		}
		// TODO 后续删掉，这里是默认给出的脑波文章
		//if len(nbaids) == 0 {
		//	nbaids = append(nbaids, []uint{2, 3, 4, 5, 6, 7}...)
		//}
		// 数组变字符串用","切割
		nbidsStr := strings.Join(strings.Split(fmt.Sprint(nbaids), " "), ",")
		// 运动方案
		var ydDiseaseArticle []request.DiseaseArticle
		// -------------------------------------------------------------获取病症关联运动部分------------------------------------------------------------- //

		if err = tx.Find(&ydDiseaseArticle, "disease_id in (?) and type = ?", bzIDs, "video").Error; err != nil {
			return err
		}

		ydIds := make([]uint, len(ydDiseaseArticle))
		for i, v := range ydDiseaseArticle {
			ydIds[i] = v.ArticleID
		}
		//根据一级过滤
		var ydArticle []hierarchy.FdArticleVideo
		if err = tx.Find(&ydArticle, "id in (?) and level_one_id = ?", ydIds, 2).Error; err != nil {
			return err
		}
		ydaids := make([]uint, len(ydArticle))
		for i, v := range ydArticle {
			ydaids[i] = v.ID
		}
		// TODO 后续删掉，这里是默认给出的运动文章
		//if len(ydaids) == 0 {
		//	ydaids = append(ydaids, []uint{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}...)
		//}
		// 数组变字符串用","切割
		ydIdsStr := strings.Join(strings.Split(fmt.Sprint(ydaids), " "), ",")
		// -------------------------------------------------------------获取体质关联体质茶部分------------------------------------------------------------- //
		var levelTwo hierarchy.LevelTwo
		//var tzName string
		//获取体质名称
		//err = tx.Table("fd_tz").First("id = ?", record.TzID).Pluck("tz_name", &tzName).Error
		var physique health.Physique
		if err = global.GVA_DB.Model(&health.Physique{}).Where("id = ?", record.TzID).First(&physique).Error; err != nil {
			return err
		}
		//获取体质levelTwoID
		if err = tx.First(&levelTwo, "`key` = ? AND level_one_id = 12", physique.ID).Error; err != nil {
			return err
		}
		// 获取体质文章
		var ztArticle []hierarchy.FdArticleGraphic
		if err = tx.Find(&ztArticle, "level_two_id = ?", levelTwo.ID).Error; err != nil {
			return err
		}
		tzcIds := make([]uint, len(ztArticle))
		for i, v := range ztArticle {
			tzcIds[i] = v.ID
		}
		// 数组变字符串用","切割
		tzcIdsStr := strings.Join(strings.Split(fmt.Sprint(tzcIds), " "), ",")
		// -------------------------------------------------------------获取功效&体质&节气&病症关联早午晚餐部分------------------------------------------------------------- //
		var pcIds []uint // 最终文章ids
		// ========================= 功效配餐 ========================= //
		// 查询用户功效ID
		if err = tx.First(&userEfficacyTag, "id = ?", record.Uid).Error; err != nil {
			return err
		}
		var fdEfficacyArticle []request.FdEfficacyArticle // 功效文章 未过滤
		if err = tx.Find(&fdEfficacyArticle, "fd_efficacy_id in (?) and type = ?", userEfficacyTag.Eids, "graphic").Error; err != nil {
			return err
		}
		gxIds := make([]uint, len(fdEfficacyArticle))
		for i, v := range fdEfficacyArticle {
			gxIds[i] = v.ArticleID
		}
		var gxArticle []hierarchy.FdArticleGraphic // 功效文章 过滤
		if err = tx.Find(&gxArticle, "id in (?) and level_one_id = ?", gxIds, 3).Error; err != nil {
			return err
		}
		for i := range gxArticle {
			pcIds = append(pcIds, gxArticle[i].ID)
		}
		// ========================= 节气配餐 ========================= //
		var pcFdJqArticle []request.FdJqArticle // 节气文章 未过滤
		err = tx.Find(&pcFdJqArticle, "fd_jq_id in (?) and type = ?", record.JqID, "graphic").Error
		if err != nil {
			return err
		}
		pcJqIds := make([]uint, len(pcFdJqArticle))
		for i, v := range pcFdJqArticle {
			pcJqIds[i] = v.ArticleID
		}
		var jqArticle []hierarchy.FdArticleGraphic // 节气文章 过滤
		err = tx.Find(&jqArticle, "id in (?) and level_one_id = ?", pcJqIds, 3).Error

		for i := range jqArticle {
			pcIds = append(pcIds, jqArticle[i].ID)
		}
		// ========================= 体质配餐 ========================= //

		var pcPhysiqueArticle []request.PhysiqueArticle // 体质文章 未过滤
		err = tx.Find(&pcPhysiqueArticle, "physique_id in (?) and type = ?", record.TzID, "graphic").Error
		if err != nil {
			return err
		}
		pcTzIds := make([]uint, len(pcPhysiqueArticle))
		for i, v := range pcPhysiqueArticle {
			pcTzIds[i] = v.ArticleID
		}
		var tzArticle []hierarchy.FdArticleGraphic // 体质文章 过滤
		err = tx.Find(&tzArticle, "id in (?) and level_one_id = ?", pcTzIds, 3).Error

		for i := range tzArticle {
			pcIds = append(pcIds, tzArticle[i].ID)
		}

		// ========================= 病症配餐 ========================= //

		var pcDiseaseArticle []request.DiseaseArticle // 病症文章 未过滤
		err = tx.Find(&pcDiseaseArticle, "disease_id in (?) and type = ?", bzIDs, "graphic").Error
		if err != nil {
			return err
		}
		pcBzIds := make([]uint, len(pcDiseaseArticle))
		for i, v := range pcDiseaseArticle {
			pcBzIds[i] = v.ArticleID
		}

		var bzArticle []hierarchy.FdArticleGraphic // 病症文章 过滤
		err = tx.Find(&bzArticle, "id in (?) and level_one_id = ?", pcBzIds, 3).Error
		for i := range bzArticle {
			pcIds = append(pcIds, bzArticle[i].ID)
		}
		// TODO 后续删掉，这里是默认给出的配餐文章
		//if len(pcIds) == 0 {
		//	pcIds = append(pcIds, []uint{595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 649}...)
		//}
		// ============ 拼接 ================= 数组变字符串用","切割

		zwwcIdsStr := strings.Join(strings.Split(fmt.Sprint(pcIds), " "), ",")

		// 生成病症报告记录
		dd := disease.DiseaseReportRecord{
			Uid:          record.Uid,
			ReportNumber: reportNumber,
			TzID:         record.TzID,
			JqID:         record.JqID,
			BzlxIDs:      record.BzlxIDs,
			BzIDs:        record.BzIDs,
		}
		if err := tx.Create(&dd).Error; err != nil {
			return err
		}

		//plan拼装
		diseaseReportPlan := []disease.DiseaseReportPlan{
			{
				DrrID:       dd.ID,
				ArticleType: 2,
				IDs:         nbidsStr,
				Types:       1,
			},
			{
				DrrID:       dd.ID,
				ArticleType: 3,
				IDs:         ydIdsStr,
				Types:       2,
			},
			{
				DrrID:       dd.ID,
				ArticleType: 1,
				IDs:         tzcIdsStr,
				Types:       3,
			},
			{
				DrrID:       dd.ID,
				ArticleType: 1,
				IDs:         zwwcIdsStr,
				Types:       4,
			},
			{
				DrrID: dd.ID,
				Types: 5,
			},
		}
		if err := tx.Create(&diseaseReportPlan).Error; err != nil {
			return err
		}
		return nil
	})
}

// SaveDiseaseHistory 保存用户病史
func (ds *DiseaseService) SaveDiseaseHistory(du *disease.UserDiseaseHistory) (err error) {
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var history disease.UserDiseaseHistory
		info := tx.Where("id = ?", du.ID).First(&history)
		if errors.Is(info.Error, gorm.ErrRecordNotFound) { // 判断是否存在数据
			info = tx.Create(&du)
		} else {
			info = tx.Where("id = ?", du.ID).Updates(du)
		}
		return err
	})
	return
}

// GetUserDiseaseHistory 获取用户病史
func (ds *DiseaseService) GetUserDiseaseHistory(id uint) (du disease.UserDiseaseHistory, err error) {
	err = global.GVA_DB.Where("id = ?", id).First(&du).Error
	return
}

// Check 检查用户受否提交过病史
func (ds *DiseaseService) Check(id uint) (err error) {
	err = global.GVA_DB.First(&assess.UserEfficacyTag{}, "id = ?", id).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("请先提交健康首要目标")
	}
	err = global.GVA_DB.First(&assess.PhysiqueQuestionLog{}, "uid = ?", id).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("请先去做体质辨别")
	}
	var rec disease.DiseaseReportRecord
	err = global.GVA_DB.Order("created_at Desc").Limit(1).First(&rec, "uid = ?", id).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("请先去做病症分析")
	}
	var plan []disease.DiseaseReportPlan
	err = global.GVA_DB.Find(&plan, "drr_id = ?", rec.ID).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("获取计划失败")
	}
	for i := range plan {
		switch plan[i].Types {
		case 1:
			if plan[i].IDs == "[]" {
				return errors.New("无匹配脑波方案")
			}
		case 2:
			if plan[i].IDs == "[]" {
				return errors.New("无匹配运动方案")
			}
		case 3:
			if plan[i].IDs == "[]" {
				return errors.New("无匹配体质茶方案")
			}
		case 4:
			if plan[i].IDs == "[]" {
				return errors.New("无匹配配餐方案")
			}
		}
	}
	return
}

// GetBrain 获取脑波方案
func (ds *DiseaseService) GetBrain(id uint, rootID string) (article hierarchy.FdArticleAudio, isCheck bool, err error) {
	today := time.Now().Format("2006-01-02")
	tomorrow := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
	var food catering.Food
	_ = global.GVA_DB.First(&food, "user_id = ? and date BETWEEN ? AND ?", id, today, tomorrow).Error

	var rec disease.DiseaseReportRecord
	err = global.GVA_DB.Order("created_at desc").First(&rec, "uid = ?", id).Error
	if err != nil {
		return article, false, err
	}
	var plan disease.DiseaseReportPlan
	err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", rec.ID, 1).Error
	if err != nil {
		return article, false, err
	}
	// plan.IDs 去除前后的[]
	plan.IDs = plan.IDs[1 : len(plan.IDs)-1]
	ids := strings.Split(plan.IDs, ",")
	searchID := utils.GetRandomNum(ids, rootID)

	if food.Brain != nil && *food.Brain != 0 {
		err = global.GVA_DB.First(&article, "id = ?", food.Brain).Error
		isCheck = true
	} else {
		err = global.GVA_DB.First(&article, "id = ?", searchID).Error
	}
	if err != nil {
		return article, false, err
	}
	return article, isCheck, nil
}

func (ds *DiseaseService) GetSport(id uint, rootID string) (article hierarchy.FdArticleVideo, isCheck bool, err error) {
	today := time.Now().Format("2006-01-02")
	tomorrow := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
	var food catering.Food
	_ = global.GVA_DB.First(&food, "user_id = ? and date BETWEEN ? AND ?", id, today, tomorrow).Error

	var rec disease.DiseaseReportRecord
	err = global.GVA_DB.Order("created_at desc").First(&rec, "uid = ?", id).Error
	if err != nil {
		return article, false, err
	}
	var plan disease.DiseaseReportPlan
	err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", rec.ID, 2).Error
	if err != nil {
		return article, false, err
	}
	// plan.IDs 去除前后的[]
	plan.IDs = plan.IDs[1 : len(plan.IDs)-1]
	ids := strings.Split(plan.IDs, ",")

	searchID := utils.GetRandomNum(ids, rootID)

	if food.Sport != nil && *food.Sport != 0 {
		err = global.GVA_DB.First(&article, "id = ?", food.Sport).Error
		isCheck = true
	} else {
		err = global.GVA_DB.First(&article, "id = ?", searchID).Error
	}
	if err != nil {
		return article, false, err
	}
	return article, isCheck, nil
}

func (ds *DiseaseService) SetBrain(id uint, rootID string) (err error) {
	today := time.Now().Format("2006-01-02")
	tomorrow := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
	err = global.GVA_DB.Model(&catering.Food{}).Where("user_id = ? and date BETWEEN ? AND ?", id, today, tomorrow).Update("brain", rootID).Error
	return err
}

func (ds *DiseaseService) SetSport(id uint, rootID string) (err error) {
	today := time.Now().Format("2006-01-02")
	tomorrow := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
	err = global.GVA_DB.Model(&catering.Food{}).Where("user_id = ? and date BETWEEN ? AND ?", id, today, tomorrow).Update("sport", rootID).Error
	return err
}

// SetPlanTips 保存方案提示
// Author [g-qs](https://github.com/g-qs)
func (ds *DiseaseService) SetPlanTips(food *catering.Food) (err error) {
	err = global.GVA_DB.Model(&catering.Food{}).Where("id = ?", food.ID).Update("tips", food.Tips).Error
	return err
}

func (ds *DiseaseService) GetSchedule(id uint) (schedule uint, tips string, err error) {
	var food catering.Food
	today := time.Now().Format("2006-01-02")
	tomorrow := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
	err = global.GVA_DB.First(&food, "user_id = ? and date BETWEEN ? AND ?", id, today, tomorrow).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return 0, "", errors.New("记录不存在")
	}
	if food.Breakfast != nil && *food.Breakfast != 0 {
		schedule += 20
	}
	if food.Lunch != nil && *food.Lunch != 0 {
		schedule += 20
	}
	if food.Dinner != nil && *food.Dinner != 0 {
		schedule += 20
	}
	//if food.Tea != nil && *food.Tea != 0 {
	//	schedule += 1
	//}
	if food.Brain != nil && *food.Brain != 0 {
		schedule += 20
	}
	if food.Sport != nil && *food.Sport != 0 {
		schedule += 20
	}
	tips = food.Tips
	return schedule, tips, err
}

// CreatePlanCompleteRecord 创建完成方案记录
func (ds *DiseaseService) CreatePlanCompleteRecord(uid uint) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var cp catering.PlanCompleteRecord
		var ud user.Division
		// 获取用户最新的一条完成方案记录
		result := tx.Order("created_at desc").First(&cp, "uid = ?", uid)
		// 判断记录是否存在
		if result.Error == nil {
			// 判断是不是今天的记录
			today := time.Now().UTC().Truncate(24 * time.Hour) // 获取今天的日期（去掉时分秒）
			if cp.CreatedAt.UTC().Truncate(24 * time.Hour).Equal(today) {
				return errors.New("已存在今日完成方案记录")
			} else {
				daysDiff := time.Since(cp.CreatedAt).Hours() / 24
				if daysDiff < 1 {
					cp.Days = 1
				} else {
					cp.Days++
				}
				// 创建新记录
				newRecord := catering.PlanCompleteRecord{
					Uid:       uid,
					CreatedAt: time.Now(),
					Days:      cp.Days,
				}
				if err := tx.Create(&newRecord).Error; err != nil {
					return err
				}
				// 获取奖牌数
				if err = tx.Where("id = ?", uid).First(&ud).Error; err != nil {
					return err
				}
				// 更新奖牌数
				if cp.Days%7 == 0 {
					ud.Bronze++
				}
				if cp.Days%28 == 0 {
					ud.Silver++
				}
				if cp.Days%365 == 0 {
					ud.Gold++
				}
				// 保存更新后信息
				if err := tx.Save(&ud).Error; err != nil {
					return err
				}
			}
		} else {
			// 创建新记录
			newRecord := catering.PlanCompleteRecord{
				Uid:       uid,
				CreatedAt: time.Now(),
				Days:      1,
			}
			if err := tx.Create(&newRecord).Error; err != nil {
				return err
			}
		}
		return nil
	})
}

// GetUserBasicInfo 获取用户基本信息
func (ds *DiseaseService) GetUserBasicInfo(uid uint) (list healthRes.BasicInfo, err error) {
	// 查询用户最近一条病症报告记录
	var record disease.DiseaseReportRecord
	err = global.GVA_DB.Where("uid = ?", uid).Order("created_at desc").
		Preload("User").Preload("Physique").Preload("SolarTerms").
		First(&record).Error
	if err != nil {
		return list, err
	}
	// 获取用户基本信息
	list.Name = record.User.Name
	list.Sex = getSexString(record.User.Sex)
	list.SolarTerms = record.SolarTerms.JqName
	list.Physique = record.Physique.Name

	var symptoms []healthRes.Symptom
	// 查询用户最近一条病症报告记录的病症类型
	var diseaseTypes []health.DiseaseList
	err = global.GVA_DB.Where("id IN (?)", strings.Split(record.BzlxIDs, ",")).Find(&diseaseTypes).Error
	if err != nil {
		return list, err
	}

	for _, diseaseType := range diseaseTypes {
		var symptom healthRes.Symptom
		symptom.DiseaseType = diseaseType.Name

		// 查询属于该病症类型的病症
		var diseases []health.Disease
		err = global.GVA_DB.Where("id IN (?) AND bzlx_id = ?", strings.Split(record.BzIDs, ","), diseaseType.ID).
			Find(&diseases).Error
		if err != nil {
			return list, err
		}

		for _, disease := range diseases {
			symptom.DiseaseList = append(symptom.DiseaseList, healthRes.DiseaseList{Disease: disease.Name})
		}

		symptoms = append(symptoms, symptom)
	}

	list.Symptom = symptoms
	return list, nil
}

// getSexString 获取性别字符串
func getSexString(sex uint) string {
	if sex == 1 {
		return "男"
	} else {
		return "女"
	}
}

func (ds *DiseaseService) GetUserList(info adminReq.UserList) (list []adminRes.User, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var users []user.User
	db := global.GVA_DB.Model(&user.User{}).Where("service_center_id = ?", info.ServiceCenterID)
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.Phone != "" {
		db = db.Where("phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.InviteUserID != 0 {
		db = db.Where("invite_user_id = ?", info.InviteUserID)
	}
	if info.StewardID != 0 {
		db = db.Where("steward_id = ?", info.StewardID)
	}
	if info.InviteUserPhone != "" {
		Inviter := global.GVA_DB.Where("phone LIKE ?", "%"+info.InviteUserPhone+"%").Find(&users).Error
		if Inviter != nil {
			return nil, 0, Inviter
		}
		var ids []uint
		for _, v := range users {
			ids = append(ids, v.ID)
		}
		db = db.Where("invite_user_id IN (?)", ids)
	}
	if info.Name != "" {
		db = db.Where("name LIKE ?", "%"+info.Name+"%")
	}
	if info.Types != nil {
		db = db.Where("types = ?", info.Types)
	}
	db.Count(&total)
	err = db.Preload("HealthManager").Preload("ProvinceInfo").Preload("CityInfo").Preload("AreaInfo").
		Limit(limit).Offset(offset).Find(&users).Error
	for _, value := range users {
		var record user.Vip
		global.GVA_DB.Order("created_at DESC").First(&record, "uid = ?", value.ID)
		var report disease.DiseaseReportRecord
		global.GVA_DB.Order("created_at DESC").First(&report, "uid = ?", value.ID)
		var tzID uint
		if report.TzID != 0 {
			tzID = report.TzID
		} else {
			tzID = 0
		}

		userInfo := adminRes.User{
			ID:           value.ID,
			Points:       value.Points,
			InviteUserID: value.InviteUserID,
			StewardID:    value.HealthManager.HmId,
			Steward:      value.HealthManager.Name,
			StewardPhone: value.HealthManager.Phone,
			Phone:        value.Phone,
			Name:         value.Name,
			Avatar:       value.Avatar,
			Types:        value.Types,
			Sex:          value.Sex,
			Birthday:     value.Birthday,
			CreatedAt:    value.CreatedAt,
			ExpiredAt:    record.ExpiredAt,
			ReportTime:   report.CreatedAt,
			Physique:     tzID,
			ProvinceName: value.ProvinceInfo.Name,
			CityName:     value.CityInfo.Name,
			AreaName:     value.AreaInfo.Name,
		}
		list = append(list, userInfo)
	}
	return list, total, err
}

func (ds *DiseaseService) GetAllUserList(info diseaseReq.UserList) (list []disease.User, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var users []user.User
	err = global.GVA_DB.Model(&user.User{}).Find(&users).Error
	var ids []uint
	for _, v := range users {
		ids = append(ids, v.ID)
	}
	db := global.GVA_DB.Select(
		"fd_user.id as id",
		"fd_user.created_at as created_at",
		"fd_user.points as points",
		"fd_user.updated_at as updated_at",
		"fd_user.invite_user_id as invite_user_id",
		"fd_user.phone as phone",
		"fd_user.name as name",
		"fd_user.avatar as avatar",
		"fd_user.types as types",
		"fd_user.sex as sex",
		"fd_user.grade as grade",
		"fd_user.birthday as birthday",
		"fd_disease_report_record.tz_id as physique",
		"fd_disease_report_record.created_at as fd_created_at",
	).Model(&disease.User{}).
		Where("fd_user.id IN ?", ids).
		Joins("LEFT JOIN fd_disease_report_record ON fd_disease_report_record.uid = fd_user.id").
		Order("fd_disease_report_record.created_at desc").
		Order("fd_user.id desc").
		Group("fd_user.id")

	if info.Phone != "" {
		db = db.Where("fd_user.phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.InviteUserID != 0 {
		db = db.Where("fd_user.invite_user_id = ?", info.InviteUserID)
	}
	if info.StewardID != 0 {
		db = db.Where("fd_user.steward_id = ?", info.StewardID)
	}
	if info.Users != "" {
		u := strings.Split(info.Users, ",")
		db = db.Where("fd_user.id in (?)", u)
	}
	if info.InviteUserPhone != "" {
		var users []disease.User
		ferr := global.GVA_DB.Where("phone LIKE ?", "%"+info.InviteUserPhone+"%").Find(&users).Error
		if ferr != nil {
			return nil, 0, ferr
		}
		var ids []uint
		for _, user := range users {
			ids = append(ids, user.ID)
		}
		db = db.Where("fd_user.invite_user_id IN (?)", ids)
	}

	if info.Name != "" {
		db = db.Where("fd_user.name LIKE ?", "%"+info.Name+"%")
	}

	if info.Types != nil {
		db = db.Where("fd_user.types = ?", info.Types)
	}

	db.Count(&total)

	err = db.Limit(limit).Offset(offset).Find(&list).Error
	return list, total, err
}

func (ds *DiseaseService) ExcelUserList(info adminReq.UserList) (file *bytes.Buffer, name string, err error) {
	//var list []disease.User
	var list []adminRes.User
	var tz []health.Physique
	tzErr := global.GVA_DB.Find(&tz).Error
	if tzErr != nil {
		return nil, "", tzErr
	}
	var tzMap = make(map[uint]string)
	for _, v := range tz {
		tzMap[v.ID] = v.Name
	}

	var userTypesMap = make(map[uint]string)
	userTypesMap[1] = "普通用户"
	userTypesMap[2] = "会员用户"
	userTypesMap[3] = "过期用户"

	db := global.GVA_DB.Debug().Select(
		"fd_user.id as id," +
			"fd_user.name as name," +
			"fd_user.sex as sex," +
			"fd_user.phone as phone," +
			"fd_user.types as types," +
			"fd_vip_open_record.expired_at as expiredAt," +
			"fd_health_manager.name as steward," +
			"fd_health_manager.phone as stewardPhone," +
			"geo_provinces.name as province," +
			"geo_cities.name as city," +
			"geo_areas.name as area," +
			"fd_user.created_at as created_at," +
			"fd_user.birthday as birthday," +
			"fd_disease_report_record.tz_id as physique," +
			"fd_user.points as points," +
			"fd_user.invite_user_id as invite_user_id," +
			"fd_user.avatar as avatar," +
			"fd_user.updated_at as updated_at," +
			"fd_user.grade as grade," + "fd_disease_report_record.created_at as fd_created_at",
	).Model(&adminRes.User{}).
		//Where("fd_user.service_center_id = ?", info.ServiceCenterID).
		Joins("LEFT JOIN fd_disease_report_record ON fd_disease_report_record.uid = fd_user.id").
		Joins("LEFT JOIN fd_health_manager ON fd_health_manager.hm_id = fd_user.steward_id").
		Joins("LEFT JOIN fd_vip_open_record ON fd_vip_open_record.uid = fd_user.id").
		Joins("LEFT JOIN geo_provinces ON geo_provinces.code = fd_user.province").
		Joins("LEFT JOIN geo_cities ON geo_cities.code = fd_user.city").
		Joins("LEFT JOIN geo_areas ON geo_areas.code = fd_user.area").
		Order("fd_disease_report_record.created_at desc").
		Order("fd_vip_open_record.created_at DESC").
		Order("fd_user.id desc").
		Group("fd_user.id")

	if info.Phone != "" {
		db = db.Where("fd_user.phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.InviteUserPhone != "" {
		var users []disease.User
		ferr := global.GVA_DB.Where("phone LIKE ?", "%"+info.InviteUserPhone+"%").Find(&users).Error
		if ferr != nil {
			return nil, "", ferr
		}
		var ids []uint
		for _, user := range users {
			ids = append(ids, user.ID)
		}
		db = db.Where("fd_user.invite_user_id IN (?)", ids)
	}
	if info.Name != "" {
		db = db.Where("fd_user.name LIKE ?", "%"+info.Name+"%")
	}
	if info.Types != nil {
		db = db.Where("fd_user.types = ?", info.Types)
	}
	err = db.Find(&list).Error
	if err != nil {
		return nil, "", err
	}
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	// Create a new sheet.
	index, err := f.NewSheet("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}
	tableTitle := []string{"名称", "性别", "手机号", "用户类型", "会员到期时间", "健管师", "服务人电话", "省", "市", "区/县", "注册日期", "生日", "用户体质", "用户积分"}
	var rows [][]string
	rows = append(rows, tableTitle)
	for _, value := range list {
		expiredAt := ""
		if value.ExpiredAt != nil {
			expiredAt = value.ExpiredAt.Format("2006-01-02")
		}
		row := []string{
			value.Name,
			getSexString(value.Sex),
			value.Phone,
			userTypesMap[value.Types],
			expiredAt,
			value.Steward,
			value.StewardPhone,
			value.ProvinceName,
			value.CityName,
			value.AreaName,
			value.CreatedAt.Format("2006-01-02"),
			value.Birthday.Format("2006-01-02"),
			tzMap[value.Physique],
			strconv.Itoa(int(value.Points)),
		}
		rows = append(rows, row)
	}
	for i, row := range rows {
		for j, colCell := range row {
			err := f.SetCellValue("Sheet1", fmt.Sprintf("%s%d", string('A'+j), i+1), colCell)
			if err != nil {
				return nil, "", err
			}
		}
	}
	f.SetActiveSheet(index)
	file, err = f.WriteToBuffer()
	if err != nil {
		return nil, "", err
	}

	return file, "会员导出表", err
}

func (ds *DiseaseService) ExcelScUserList(info adminReq.UserList, ScID uint) (file *bytes.Buffer, name string, err error) {
	var list []adminRes.User
	var tz []health.Physique
	var stations []system.SysUser
	// 查询所有的服务中心
	if servicesErr := global.GVA_DB.Where("authority_id = 444 AND creator = ?", ScID).Find(&stations).Error; servicesErr != nil {
		return nil, "", servicesErr
	}
	var ids []uint
	for _, v := range stations {
		ids = append(ids, v.ID)
	}
	tzErr := global.GVA_DB.Find(&tz).Error
	if tzErr != nil {
		return nil, "", tzErr
	}
	var tzMap = make(map[uint]string)
	for _, v := range tz {
		tzMap[v.ID] = v.Name
	}
	var userTypesMap = make(map[uint]string)
	userTypesMap[1] = "普通用户"
	userTypesMap[2] = "会员用户"
	userTypesMap[3] = "过期用户"
	db := global.GVA_DB.Debug().Select(
		"fd_user.id as id,"+
			"fd_user.name as name,"+
			"fd_user.sex as sex,"+
			"fd_user.phone as phone,"+
			"fd_user.types as types,"+
			"fd_vip_open_record.expired_at as expiredAt,"+
			"fd_health_manager.name as steward,"+
			"fd_health_manager.phone as stewardPhone,"+
			"geo_provinces.name as province,"+
			"geo_cities.name as city,"+
			"geo_areas.name as area,"+
			"fd_user.created_at as created_at,"+
			"fd_user.birthday as birthday,"+
			"fd_disease_report_record.tz_id as physique,"+
			"fd_user.points as points,"+
			"fd_user.invite_user_id as invite_user_id,"+
			"fd_user.avatar as avatar,"+
			"fd_user.updated_at as updated_at,"+
			"fd_user.grade as grade,"+"fd_disease_report_record.created_at as fd_created_at",
	).Model(&adminRes.User{}).Where("fd_user.service_center_id IN (?)", ids)
	if info.Phone != "" {
		db = db.Where("fd_user.phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.InviteUserPhone != "" {
		var users []disease.User
		ferr := global.GVA_DB.Where("phone LIKE ?", "%"+info.InviteUserPhone+"%").Find(&users).Error
		if ferr != nil {
			return nil, "", ferr
		}
		var ids []uint
		for _, user := range users {
			ids = append(ids, user.ID)
		}
		db = db.Where("fd_user.invite_user_id IN (?)", ids)
	}
	if info.Name != "" {
		db = db.Where("fd_user.name LIKE ?", "%"+info.Name+"%")
	}
	if info.Types != nil {
		db = db.Where("fd_user.types = ?", info.Types)
	}
	err = db.Joins("LEFT JOIN fd_disease_report_record ON fd_disease_report_record.uid = fd_user.id").
		Joins("LEFT JOIN fd_health_manager ON fd_health_manager.hm_id = fd_user.steward_id").
		Joins("LEFT JOIN fd_vip_open_record ON fd_vip_open_record.uid = fd_user.id").
		Joins("LEFT JOIN geo_provinces ON geo_provinces.code = fd_user.province").
		Joins("LEFT JOIN geo_cities ON geo_cities.code = fd_user.city").
		Joins("LEFT JOIN geo_areas ON geo_areas.code = fd_user.area").
		Order("fd_disease_report_record.created_at desc").
		Order("fd_vip_open_record.created_at DESC").
		Order("fd_user.id desc").
		Group("fd_user.id").Find(&list).Error
	if err != nil {
		return nil, "", err
	}
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	// Create a new sheet.
	index, err := f.NewSheet("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}
	tableTitle := []string{"名称", "性别", "手机号", "用户类型", "会员到期时间", "健管师", "服务人电话", "省", "市", "区/县", "注册日期", "生日", "用户体质", "用户积分"}
	var rows [][]string
	rows = append(rows, tableTitle)
	for _, value := range list {
		expiredAt := ""
		if value.ExpiredAt != nil {
			expiredAt = value.ExpiredAt.Format("2006-01-02")
		}
		row := []string{
			value.Name,
			getSexString(value.Sex),
			value.Phone,
			userTypesMap[value.Types],
			expiredAt,
			value.Steward,
			value.StewardPhone,
			value.ProvinceName,
			value.CityName,
			value.AreaName,
			value.CreatedAt.Format("2006-01-02"),
			value.Birthday.Format("2006-01-02"),
			tzMap[value.Physique],
			strconv.Itoa(int(value.Points)),
		}
		rows = append(rows, row)
	}
	for i, row := range rows {
		for j, colCell := range row {
			err := f.SetCellValue("Sheet1", fmt.Sprintf("%s%d", string('A'+j), i+1), colCell)
			if err != nil {
				return nil, "", err
			}
		}
	}
	f.SetActiveSheet(index)
	file, err = f.WriteToBuffer()
	if err != nil {
		return nil, "", err
	}
	return file, "会员导出表", err
}

func (ds *DiseaseService) GetUserRecord(userID string, flag string) (req *disease.DiseaseReportPlan, err error) {
	var record disease.DiseaseReportRecord
	err = global.GVA_DB.First(&record, "uid = ?", userID).Order("created_at desc").Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, errors.New("该用户没有做过AI评估的病症分析")
	}
	var plan disease.DiseaseReportPlan
	switch flag {
	case "naobo":
		err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", record.ID, 1).Error
		if err != nil {
			return nil, err
		}
		return &plan, nil
	case "yundong":
		err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", record.ID, 2).Error
		if err != nil {
			return nil, err
		}
		return &plan, nil
	case "yinshi":
		err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", record.ID, 4).Error
		if err != nil {
			return nil, err
		}
		return &plan, nil
	case "ganyu":
		err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", record.ID, 5).Error
		if err != nil {
			return nil, err
		}
		return &plan, nil
	}
	return nil, nil
}

func (ds *DiseaseService) SetUserRecord(plan disease.DiseaseReportPlan, flag string) (err error) {
	switch flag {
	case "naobo":
		return global.GVA_DB.First(&disease.DiseaseReportPlan{}, "id = ? ", plan.ID).Update("ids", plan.IDs).Error
	case "yundong":
		return global.GVA_DB.First(&disease.DiseaseReportPlan{}, "id = ?", plan.ID).Update("ids", plan.IDs).Error
	case "yinshi":
		return global.GVA_DB.First(&disease.DiseaseReportPlan{}, "id = ? ", plan.ID).Update("ids", plan.IDs).Error
	case "ganyu":
		return global.GVA_DB.First(&disease.DiseaseReportPlan{}, "id = ? ", plan.ID).Update("money", plan.Money).Update("content", plan.Content).Error
	}
	return nil
}

func (ds *DiseaseService) GetArticle() (res map[string][]map[string]any, err error) {
	var naoboArticles []request.DiseaseArticle
	var yundongArticles []request.DiseaseArticle
	var yinshiArticles []hierarchy.FdArticleGraphic

	var naoboRes []map[string]any
	var yundongRes []map[string]any
	var yinshiRes []map[string]any
	err = global.GVA_DB.Preload("FdArticleAudio").Group("article_id").Find(&naoboArticles, "type = ?", "audio").Error
	for _, article := range naoboArticles {
		if article.FdArticleAudio == nil {
			continue
		}
		naoboRes = append(naoboRes, map[string]any{
			"key":   article.ArticleID,
			"value": article.FdArticleAudio.Title,
		})
	}
	if err != nil {
		return nil, err
	}

	err = global.GVA_DB.Preload("FdArticleVideo").Group("article_id").Find(&yundongArticles, "type = ?", "video").Error
	for _, article := range yundongArticles {
		yundongRes = append(yundongRes, map[string]any{
			"key":   article.ArticleID,
			"value": article.FdArticleVideo.Title,
		})
	}
	if err != nil {
		return nil, err
	}
	err = global.GVA_DB.Find(&yinshiArticles, "level_two_id = ?", 49).Error
	for _, article := range yinshiArticles {
		yinshiRes = append(yinshiRes, map[string]any{
			"key":   article.ID,
			"value": article.Title,
		})
	}
	if err != nil {
		return nil, err
	}
	res = make(map[string][]map[string]any)
	res["naobo"] = naoboRes
	res["yundong"] = yundongRes
	res["yinshi"] = yinshiRes

	return
}

func (ds *DiseaseService) OpenVip(hm_id uint, uid string, authority uint, vipType string) error {

	if authority != 888 {
		var count int64
		err := global.GVA_DB.Model(disease.OpenLog{}).Where("hm_id = ?", hm_id).Count(&count).Error
		if err != nil {
			return err
		}
		if count > 100 {
			return errors.New("超过开通vip人数")
		}
	}
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		err := tx.Create(&disease.OpenLog{
			HMID: hm_id,
			UID:  uid,
		}).Error
		if err != nil {
			return err
		}

		err = tx.First(&disease.User{}, "id = ?", uid).Update("types", 2).Error

		vtype, _ := strconv.Atoi(vipType)

		var dataMap = make(map[string]int)
		dataMap["0"] = 0
		dataMap["1"] = 30
		dataMap["2"] = 90
		dataMap["3"] = 180
		dataMap["4"] = 365

		//ExpiredAt := time.Now()
		var expiredAt time.Time

		if day, ok := dataMap[vipType]; ok {
			//ExpiredAt.AddDate(0, 0, day)
			expiredAt = time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Now().Location()).AddDate(0, 0, day)
		}

		var applyForAt time.Time // 更新后申请时间
		applyForAt = time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Now().Location())

		// 获取当前用户开通记录
		recordErr := tx.Order("id DESC").First(&user.Vip{}, "uid = ?", uid)
		if errors.Is(recordErr.Error, gorm.ErrRecordNotFound) { // 判断是否存在数据
			uintUid, _ := strconv.ParseUint(uid, 10, 64)
			if createErr := tx.Create(&user.Vip{
				Uid:        uint(uintUid),
				CreatedAt:  applyForAt,
				UpdatedAt:  time.Now(),
				ExpiredAt:  &expiredAt,
				ApplyForAt: applyForAt,
				VipType:    uint(vtype),
				Status:     2,
			}).Error; createErr != nil {
				return createErr
			}
		} else {
			if upErr := tx.Order("id DESC").First(&user.Vip{}, "uid = ?", uid).Updates(map[string]interface{}{
				"expired_at":   expiredAt,
				"apply_for_at": applyForAt,
				"vip_type":     uint(vtype),
				"status":       2}).Error; upErr != nil {
				return upErr
			}
		}
		return nil
	})

}

func (ds *DiseaseService) UserHealth(id string) (list any, err error) {

	//db := global.GVA_DB.Model(&disease.OpenLog{}).Order("id desc")
	return nil, nil
}

func (ds *DiseaseService) SetUserPoints(id string, points string) (err error) {
	return global.GVA_DB.Model(&disease.User{}).Where("id = ?", id).Update("points", points).Error
}

func (ds *DiseaseService) GetHealthData(id string) (datas map[string]any, err error) {
	var phy []assess.PhysiqueQuestionLog
	err = global.GVA_DB.Where("uid = ?", id).Order("created_at desc").Limit(5).Find(&phy).Error
	if err != nil {
		return nil, err
	}
	var y []string
	var blood_sugar []string
	var blood_oxygen []string
	var heart_rate []string
	var low_pressure []string
	var high_pressure []string
	for i := range phy {
		y = append(y, phy[i].CreatedAt.Format("2006-01-02"))
		blood_sugar = append(blood_sugar, phy[i].BloodSugar)
		blood_oxygen = append(blood_oxygen, phy[i].BloodConcentration)
		heart_rate = append(heart_rate, phy[i].HRres)

		low_pressures := strings.Split(phy[i].LowTension, ",")
		high_pressures := strings.Split(phy[i].HighTension, ",")

		low_pressure = append(low_pressure, getMaxNum(low_pressures))
		high_pressure = append(high_pressure, getMaxNum(high_pressures))
	}
	datas = make(map[string]any)
	datas["y"] = y
	datas["blood_sugar"] = blood_sugar
	datas["blood_oxygen"] = blood_oxygen
	datas["heart_rate"] = heart_rate
	datas["low_pressure"] = low_pressure
	datas["high_pressure"] = high_pressure
	return datas, nil
}

func (ds *DiseaseService) GetHisPlan(id, types, selectTypes string) (rePlan *diseaseRes.HisPlan, err error) {
	//types 0是脑波方案 1是机能方案 2是饮食方案；
	var record disease.DiseaseReportRecord
	err = global.GVA_DB.Order("created_at Desc").Limit(1).First(&record, "uid = ?", id).Error
	if err != nil {
		return nil, err
	}
	var plan disease.DiseaseReportPlan
	var articles []request.DiseaseArticle

	var res []diseaseRes.PlanInfo

	switch types {
	case "0":
		err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", record.ID, 1).Error
		if err != nil {
			return nil, err
		}
		err = global.GVA_DB.Preload("FdArticleAudio").Preload("FdArticleAudio.LevelOne").Preload("FdArticleAudio.LevelTwo").Group("article_id").Find(&articles, "type = ?", "audio").Error
		for _, article := range articles {
			if article.FdArticleAudio == nil {
				continue
			}
			selectedNum := selected(plan.IDs, article.ArticleID)
			switch selectTypes {
			case "0":
				res = append(res, diseaseRes.PlanInfo{
					ID:            article.FdArticleAudio.ID,
					Title:         article.FdArticleAudio.Title,
					Cover:         article.FdArticleAudio.Cover,
					OneLevelValue: article.FdArticleAudio.LevelOne.Value,
					TwoLevelValue: article.FdArticleAudio.LevelTwo.Value,
					Select:        selectedNum,
				})
			case "1":
				if selectedNum == 1 {
					res = append(res, diseaseRes.PlanInfo{
						ID:            article.FdArticleAudio.ID,
						Title:         article.FdArticleAudio.Title,
						Cover:         article.FdArticleAudio.Cover,
						OneLevelValue: article.FdArticleAudio.LevelOne.Value,
						TwoLevelValue: article.FdArticleAudio.LevelTwo.Value,
						Select:        selectedNum,
					})
				}
			case "2":
				if selectedNum == 2 {
					res = append(res, diseaseRes.PlanInfo{
						ID:            article.FdArticleAudio.ID,
						Title:         article.FdArticleAudio.Title,
						Cover:         article.FdArticleAudio.Cover,
						OneLevelValue: article.FdArticleAudio.LevelOne.Value,
						TwoLevelValue: article.FdArticleAudio.LevelTwo.Value,
						Select:        selectedNum,
					})
				}
			}

		}
		if err != nil {
			return nil, err
		}
	case "1":
		err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", record.ID, 2).Error
		if err != nil {
			return nil, err
		}
		err = global.GVA_DB.Preload("FdArticleVideo").Preload("FdArticleVideo.LevelOne").Preload("FdArticleVideo.LevelTwo").Group("article_id").Find(&articles, "type = ?", "video").Error
		for _, article := range articles {
			selectedNum := selected(plan.IDs, article.ArticleID)
			switch selectTypes {
			case "0":
				res = append(res, diseaseRes.PlanInfo{
					ID:            article.FdArticleVideo.ID,
					Title:         article.FdArticleVideo.Title,
					Cover:         article.FdArticleVideo.Cover,
					OneLevelValue: article.FdArticleVideo.LevelOne.Value,
					TwoLevelValue: article.FdArticleVideo.LevelTwo.Value,
					Select:        selectedNum,
				})
			case "1":
				if selectedNum == 1 {
					res = append(res, diseaseRes.PlanInfo{
						ID:            article.FdArticleVideo.ID,
						Title:         article.FdArticleVideo.Title,
						Cover:         article.FdArticleVideo.Cover,
						OneLevelValue: article.FdArticleVideo.LevelOne.Value,
						TwoLevelValue: article.FdArticleVideo.LevelTwo.Value,
						Select:        selectedNum,
					})
				}
			case "2":
				if selectedNum == 2 {
					res = append(res, diseaseRes.PlanInfo{
						ID:            article.FdArticleVideo.ID,
						Title:         article.FdArticleVideo.Title,
						Cover:         article.FdArticleVideo.Cover,
						OneLevelValue: article.FdArticleVideo.LevelOne.Value,
						TwoLevelValue: article.FdArticleVideo.LevelTwo.Value,
						Select:        selectedNum,
					})
				}
			}

		}
		if err != nil {
			return nil, err
		}
	case "2":
		err = global.GVA_DB.First(&plan, "drr_id = ? and types = ?", record.ID, 4).Error
		if err != nil {
			return nil, err
		}
		var yinshiArticles []hierarchy.FdArticleGraphic
		err = global.GVA_DB.Preload("LevelOne").Preload("LevelTwo").Find(&yinshiArticles, "level_two_id = ?", 49).Error
		for _, article := range yinshiArticles {
			selectedNum := selected(plan.IDs, article.ID)
			switch selectTypes {
			case "0":
				res = append(res, diseaseRes.PlanInfo{
					ID:            article.ID,
					Title:         article.Title,
					Cover:         article.Cover,
					OneLevelValue: article.LevelOne.Value,
					TwoLevelValue: article.LevelTwo.Value,
					Select:        selectedNum,
				})
			case "1":
				if selectedNum == 1 {
					res = append(res, diseaseRes.PlanInfo{
						ID:            article.ID,
						Title:         article.Title,
						Cover:         article.Cover,
						OneLevelValue: article.LevelOne.Value,
						TwoLevelValue: article.LevelTwo.Value,
						Select:        selectedNum,
					})
				}
			case "2":
				if selectedNum == 2 {
					res = append(res, diseaseRes.PlanInfo{
						ID:            article.ID,
						Title:         article.Title,
						Cover:         article.Cover,
						OneLevelValue: article.LevelOne.Value,
						TwoLevelValue: article.LevelTwo.Value,
						Select:        selectedNum,
					})
				}
			}

		}
		if err != nil {
			return nil, err
		}
	}

	rePlan = &diseaseRes.HisPlan{
		ID:   plan.ID,
		Ids:  plan.IDs,
		List: res,
	}

	return
}

func (ds *DiseaseService) SetHisPlan(plan disease.DiseaseReportPlan) (err error) {
	switch plan.Types {
	case 1:
		return global.GVA_DB.First(&disease.DiseaseReportPlan{}, "id = ? ", plan.ID).Update("ids", plan.IDs).Error
	case 2:
		return global.GVA_DB.First(&disease.DiseaseReportPlan{}, "id = ? ", plan.ID).Update("ids", plan.IDs).Error
	case 4:
		return global.GVA_DB.First(&disease.DiseaseReportPlan{}, "id = ? ", plan.ID).Update("ids", plan.IDs).Error
	}
	return nil
}

// 获取数字字符串数组的最大值
func getMaxNum(arr []string) string {
	max := arr[0]
	for _, v := range arr {
		if v > max {
			max = v
		}
	}
	return max
}

func selected(ids string, id uint) int {
	ids = strings.Trim(ids, "[]")

	idSlice := strings.Split(ids, ",")

	idStr := strconv.Itoa(int(id))

	for _, v := range idSlice {
		if v == idStr {
			return 1
		}
	}
	return 2
}
